
#include <iostream>
#include <windows.h>
#include <string>
#include "user.h"

using namespace std;


/**
 * 创建窗口
 * @param winName 窗口名称
 * @param value 窗口标题名称
 * @param hIns
 * @param x x 坐标
 * @param y y 坐标
 * @param w 宽
 * @param h 长
 * @return
 */
HWND createWin(const char *winName, const char *value, HINSTANCE hIns, int x, int y, int w, int h);

/**
 * 创建按钮
 * @param value 按钮的内容
* @param parent  父容器
 * @param id 控件id
 * @param x x 坐标
 * @param y y 坐标
 * @param w 宽
 * @param h 长
* @return null: 创建失败, 否则成功
 */
HWND createButton(const char *value, HWND parent, HINSTANCE hIns, int id, int x, int y, int w, int h);

/**
 * 创建编辑框
 * @param parent 父容器
 * @param hIns
 * @param id 控件id
 * @param x x 坐标
 * @param y y 坐标
 * @param w 宽
 * @param h 长
 * @return
 */
HWND createEdit(HWND parent, HINSTANCE hIns, int id, int x, int y, int w, int h);

/**
 * 创建静态文本框
 * @param parent 父容器
 * @param hIns
 * @param value 文本内容
 * @param id 控件id
 * @param x x 坐标
 * @param y y 坐标
 * @param w 宽
 * @param h 长
 * @return
 */
HWND createTextBox(HWND parent, HINSTANCE hIns, const char *value, int id, int x, int y, int w, int h);

/**
 * 窗体消息显示
 * @param hwnd 句柄
 * @param result 显示消息
 * @param type 消息类型, 常用有: info,error,Warnings
 */
void messageShow(HWND hwnd, const char *result, UINT type);

/**
 * 读取控件内容
 * @param hwnd 句柄
 * @param id 控件id
 * @param result 读取内容
 * @return
 */
bool readWinText(HWND hwnd, int id, char *result);

/**
 * 清空控件内容
 * @param hwnd 当前句柄
 * @param id 控件id
 */
void clearWinText(HWND hwnd, int id);


/**
 * 用户验证
 * @param hwnd
 * @param type 处理类型, 登录/注册
 * @return
 */
bool userCheck(HWND hwnd, string type);

// 事件触发回调
LRESULT CALLBACK WndProc(HWND hwnd, UINT msgId, WPARAM wparam, LPARAM lparam) {
    // 获取当前触发控件的id
    int value = LOWORD(wparam);
    switch (msgId) {
        case WM_DESTROY: {
//            printf("exit: %d", value);
            PostQuitMessage(0);
            return 0;
        }
        case WM_COMMAND: {
//            printf("事件触发: %d \n", value);
            switch (value) {
                case 1: {
                    // login
                    userCheck(hwnd, "login");
                    break;
                }
                case 2: {
                    // regis
                    userCheck(hwnd, "regis");
                    break;
                }
            }
        }
            return 0;
    }
    fflush(stdout);
    return DefWindowProc(hwnd, msgId, wparam, lparam);
}

bool userCheck(HWND hwnd, string type) {
    char *username = new char[256];
    char *password = new char[256];
    bool success = true;
    bool login_success = true;
    bool reg_success = true;
    // 获取账号,密码
    if (readWinText(hwnd, 3, username) && readWinText(hwnd, 4, password)) {
        string info;
        bool state;
        if (type == "login") {
            info = "登录成功!";
            state = login(username, password);
            if (!state) login_success = false;
        } else if (type == "regis") {
            info = "注册成功!";
            state = registration(username, password);
            if (!state) reg_success = false;
        }

        if (state) {
            messageShow(hwnd, info.c_str(), MB_OK);
        } else {
            success = false;
        }
    } else {
        success = false;
    }

    if (!success) {
        // 清空控件内容
        clearWinText(hwnd, 3);
        clearWinText(hwnd, 4);
        string result = "账号/密码不能为空!";
        if (!login_success) {
            result = "账号/密码错误!";
        }
        if (!reg_success) {
            result = "该用户已经存在!";
        }
        // 提示不能为空
        messageShow(hwnd, result.c_str(), MB_ICONWARNING);
    }
    return login_success;
}


// 主函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hpreIns, LPSTR lpCmdLine, int nCmdShow) {

    // 生成模拟数据
    initDatabase();

    // 在内存中创建窗口
    HWND hwnd = createWin("Main", "LOGIN", hIns, 613, 363, 450, 350);
    // 创建按钮, 指定到 窗口中
    createButton("登   录", hwnd, hIns, 1, 100, 200, 42, 32);
    createButton("注   册", hwnd, hIns, 2, 200, 200, 42, 32);

    int y = 100;
    const char *value = "输入账号:";
    for (int i = 0; i < 2; i++) {
        // 创建输入框
        createEdit(hwnd, hIns, i + 3, 150, y, 200, 25);
        // 创建文本框
        createTextBox(hwnd, hIns, value, i + 5, 65, y, 200, 25);
        value = "输入密码:";
        y += 50;
    }


    // 隐藏控制台
    HWND consoleWindow = GetConsoleWindow();
    if (consoleWindow != NULL) {
        ShowWindow(consoleWindow, SW_HIDE);
    }
    // 显示窗口
    ShowWindow(hwnd, SW_SHOW);


    // 消息循环
    MSG msg = {nullptr};
    while (GetMessage(&msg, nullptr, 0, 0)) {
        TranslateMessage(&msg);
        // 将消息交给窗口处理函数
        DispatchMessage(&msg);
    }
    return 0;
}


HWND createButton(const char *value, HWND parent, HINSTANCE hIns, int id, int x, int y, int w, int h) {
    int length = strlen(value) * 6;
    HWND button = CreateWindow("button", value, WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                               x, y, length, h, parent,
                               (HMENU) reinterpret_cast<HMENU>(id),
                               hIns,/*(HINSTANCE) GetWindowLong(parent, GWLP_HINSTANCE),*/
                               nullptr);
    if (!button) {
        MessageBox(nullptr, "按钮创建失败!", "错误", MB_ICONERROR);
        return nullptr;
    }
    return button;
}

HWND createEdit(HWND parent, HINSTANCE hIns, int id, int x, int y, int w, int h) {
    HWND input = CreateWindowEx(WS_EX_CLIENTEDGE, "edit", nullptr,
                                WS_CHILD | WS_VISIBLE | ES_LEFT | ES_WANTRETURN | ES_AUTOVSCROLL,
                                x, y, w, h, parent,
                                (HMENU) reinterpret_cast<HMENU>(id), hIns, nullptr);
    if (!input) {
        MessageBox(nullptr, "输入框创建失败!", "错误", MB_ICONERROR);
        return nullptr;
    }
    return input;
}

HWND createTextBox(HWND parent, HINSTANCE hIns, const char *value, int id, int x, int y, int w, int h) {
    int length = strlen(value) * 6;
    HWND textBox = CreateWindow("static", value, WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL,
                                x, y, length, h, parent,
                                (HMENU) reinterpret_cast<HMENU>(id), hIns, nullptr);
    if (!textBox) {
        MessageBox(nullptr, "文本创建失败!", "错误", MB_ICONERROR);
        return nullptr;
    }
    return textBox;
}

HWND createWin(const char *winName, const char *value, HINSTANCE hIns, int x, int y, int w, int h) {

    // 注册窗口类
    WNDCLASS wndclass = {0};
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 2);
    wndclass.hCursor = nullptr;
    wndclass.hIcon = nullptr;
    wndclass.hInstance = hIns;
    wndclass.lpszClassName = winName;
    wndclass.lpfnWndProc = WndProc;
    wndclass.lpszMenuName = nullptr;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;

    // 将赋值写入操作系统
    RegisterClass(&wndclass);
    // 在内存中创建窗口
    HWND win = CreateWindow(winName, value, WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME, x, y, w, h,
                            nullptr, nullptr, hIns, nullptr);
    if (!win) {
        MessageBox(nullptr, "创建窗口失败!", "错误", MB_ICONERROR);
        return nullptr;
    }
    return win;
}


void messageShow(HWND hwnd, const char *result, UINT type) {
    MessageBox(hwnd, reinterpret_cast<LPCSTR>(result), "消息", type);
}


bool readWinText(HWND hwnd, int id, char *result) {
    boolean isNotEmpty = GetDlgItemText(hwnd, id, result, 256);
    if (isNotEmpty) {
//        printf("读取控件输入的数据: %s \n", result);
        return true;
    }
    return false;
}


void clearWinText(HWND hwnd, int id) {
    // 清空控件内容
    SetDlgItemText(hwnd, id, "");
}